﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using System.Web.Configuration;
using System.Data;
using System.Diagnostics;
using MySql;
using MySql.Data;
using MySql.Data.MySqlClient;

using System.Text.RegularExpressions;
using System.Collections.Specialized;
using System.Web.Security;
using System.Security.Principal;

using System.Net;
using System.Net.Mail;
using System.Text;
using System.Security.Cryptography;

namespace doris.Agent {

    public class AlphaNumericPasswordGenerator {
        /// <summary>
        /// Generates a password with the given character length.
        /// </summary>
        /// <param name="Length"></param>
        /// <returns></returns>
        public string Generate(int Length) {
            /* Alternative method
            Random random = new Random();
            return MD5Hash(random.Next(0,1000).ToString());
            */

            if (Length < 5) {
                Length = 5;
            }

            Random random = new Random();
            string password = MD5Hash(random.Next().ToString()).Substring(0, 10);
            string newPass = "";

            // Uppercase at random
            random = new Random();
            for (int i = 0; i < password.Length; i++) {
                if (random.Next(0, 2) == 1)
                    newPass += password.Substring(i, 1).ToUpper();
                else
                    newPass += password.Substring(i, 1);
            }

            return newPass;
        }

        private string MD5Hash(string Data) {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] hash = md5.ComputeHash(Encoding.ASCII.GetBytes(Data));

            StringBuilder stringBuilder = new StringBuilder();
            foreach (byte b in hash) {
                stringBuilder.AppendFormat("{0:x2}", b);
            }
            return stringBuilder.ToString();
        }
    }

    public partial class newTicket : System.Web.UI.Page {
        public class DorisUser {
            public String CustID { get; set; }
            public String Username { get; set; }
            public String Password { get; set; }
            public int Exists { get; set; }
        }

        public class TicketStatus {
            public int TicketID { get; set; }
            public String Service { get; set; }
            public String Priority { get; set; }
            public String Status { get; set; }
        }
        public class MAILConnection {
            public String ConnectionName { get; set; }
            public String Server { get; set; }
            public Boolean UseCredentials { get; set; }
            public String Username { get; set; }
            public String Password { get; set; }
            public int Port { get; set; }
            public Boolean UseSSL { get; set; }
            public Boolean Enabled { get; set; }
        }
        public MAILConnection FetchSMTP() {
            MAILConnection smtp = new MAILConnection();
            MySqlConnection conn = new MySqlConnection(WebConfigurationManager.ConnectionStrings["localConnectionString"].ConnectionString);
            try
            {
                conn.Open();
                MySqlCommand cmd = new MySqlCommand();
                cmd.Connection = conn;

                //          Console.WriteLine("Connecting to MySQL...");
                //                cmd.CommandText = "getTicketStatus";
                cmd.CommandText = "getEnabledSmtp";
                cmd.CommandType = CommandType.StoredProcedure;

                MySqlDataReader reader = cmd.ExecuteReader();

                if (reader.Read())
                {
                    smtp.ConnectionName = reader.GetValue(1).ToString();
                    smtp.Server = reader.GetValue(2).ToString();
                    smtp.UseCredentials = (int.Parse(reader.GetValue(3).ToString()) == 1 ? true : false);
                    smtp.Username = reader.GetValue(4).ToString();
                    smtp.Password = reader.GetValue(5).ToString();
                    smtp.Port = int.Parse(reader.GetValue(6).ToString());
                    smtp.UseSSL = (int.Parse(reader.GetValue(7).ToString()) == 1 ? true : false);
                    smtp.Enabled = (int.Parse(reader.GetValue(8).ToString()) == 1 ? true : false);
                }
                
                cmd.Dispose();
            }
            catch (MySql.Data.MySqlClient.MySqlException ex)
            {
                Debug.WriteLine("Error " + ex.Number + " has occurred: " + ex.Source.ToString());
            }
            finally
            {
               
                conn.Close();
            }
            return smtp;
        }


        protected void storeCurrentStatus(int TicketID) {
            MySqlConnection conn = new MySqlConnection(WebConfigurationManager.ConnectionStrings["localConnectionString"].ConnectionString);
            try {
                conn.Open();
                MySqlCommand cmd = new MySqlCommand();
                cmd.Connection = conn;

                cmd.CommandText = "storeTicketStatus";
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add(new MySqlParameter("@in_ticketid", MySqlDbType.Int32));
                cmd.Parameters["@in_ticketid"].Value = TicketID;
                cmd.Parameters["@in_ticketid"].Direction = ParameterDirection.Input;

                cmd.Parameters.Add(new MySqlParameter("@in_ticketstatusid", MySqlDbType.Int32));
                cmd.Parameters["@in_ticketstatusid"].Value = int.Parse(lStatus.SelectedValue);
                cmd.Parameters["@in_ticketstatusid"].Direction = ParameterDirection.Output;

                cmd.ExecuteNonQuery();

                cmd.Dispose();
            } catch (MySql.Data.MySqlClient.MySqlException ex) {
                Debug.WriteLine("Error " + ex.Number + " has occurred: " + ex.Message);

               
            } finally {
                conn.Close();
            }
        }

        public static TicketStatus GetTicketStatus(int TicketID) {
            TicketStatus output = new TicketStatus();
            MySqlConnection conn = new MySqlConnection(WebConfigurationManager.ConnectionStrings["localConnectionString"].ConnectionString);
            try {
                conn.Open();
                MySqlCommand cmd = new MySqlCommand();
                cmd.Connection = conn;

                //          Console.WriteLine("Connecting to MySQL...");
                //                cmd.CommandText = "getTicketStatus";
                cmd.CommandText = "getTicketStatus";
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add(new MySqlParameter("@in_ticketid", MySqlDbType.VarChar));
                cmd.Parameters["@in_ticketid"].Value = TicketID;
                cmd.Parameters["@in_ticketid"].Direction = ParameterDirection.Input;

                cmd.Parameters.Add(new MySqlParameter("@out_service", MySqlDbType.VarChar));
                cmd.Parameters["@out_service"].Direction = ParameterDirection.Output;

                cmd.Parameters.Add(new MySqlParameter("@out_priority", MySqlDbType.VarChar));
                cmd.Parameters["@out_priority"].Direction = ParameterDirection.Output;

                cmd.Parameters.Add(new MySqlParameter("@out_status", MySqlDbType.VarChar));
                cmd.Parameters["@out_status"].Direction = ParameterDirection.Output;

                cmd.Parameters.Add(new MySqlParameter("@out_ticketstatusid", MySqlDbType.Int32));
                cmd.Parameters["@out_ticketstatusid"].Direction = ParameterDirection.Output;

                cmd.ExecuteNonQuery();

                output.TicketID = TicketID;
                if (cmd.Parameters["@out_service"].Value != null)
                    output.Service = cmd.Parameters["@out_service"].Value.ToString();
                if (cmd.Parameters["@out_priority"].Value != null)
                    output.Priority = cmd.Parameters["@out_priority"].Value.ToString();
                if (cmd.Parameters["@out_status"].Value != null)
                    output.Status = cmd.Parameters["@out_status"].Value.ToString();

                cmd.Dispose();
            } catch (MySql.Data.MySqlClient.MySqlException ex) {
                Console.WriteLine("Error " + ex.Number + " has occurred: " + ex.Message);
            } finally {
                conn.Close();
            }
            return output;
        }

        public Boolean SendTicketResponse(int TicketID, DorisUser doris, TicketStatus data, String subject, String sMessage, bool reply) {
            MySqlConnection conn = new MySqlConnection(WebConfigurationManager.ConnectionStrings["localConnectionString"].ConnectionString);
            String email = String.Empty;
        
            // String sender, String email, String fullname
            String sender = "doris@mpdemo.no";
            String fullname = "";

            String Message = String.Empty;
            if (!reply) {
                // String subject, String fullname, String message, DorisUser doris, TicketStatus data, bool reply
                try {
                    conn.Open();
                    MySqlCommand cmd = new MySqlCommand();
                    cmd.Connection = conn;

                    //          Console.WriteLine("Connecting to MySQL...");
                    //                cmd.CommandText = "getTicketStatus";
                    cmd.CommandText = "getDefaultResponse";
                    cmd.CommandType = CommandType.StoredProcedure;

                    cmd.Parameters.Add(new MySqlParameter("@out_message", MySqlDbType.Text));
                    cmd.Parameters["@out_message"].Direction = ParameterDirection.Output;

                    cmd.ExecuteNonQuery();

                    Message = HttpUtility.HtmlDecode(cmd.Parameters["@out_message"].Value.ToString());
                    cmd.Dispose();


                } catch (MySql.Data.MySqlClient.MySqlException ex) {
                    Debug.WriteLine("Error " + ex.Number + " has occurred: " + ex.Message);
                } finally {
                    conn.Close();
                }

                Message = Message.Replace("[fullname]", fullname);
                Message = Message.Replace("[ticketid]", data.TicketID.ToString());
                Message = Message.Replace("[subject]", subject);
                Message = Message.Replace("[department]", data.Service);
                Message = Message.Replace("[priority]", data.Priority);
                Message = Message.Replace("[status]", data.Status);
                Message = Message.Replace("[url]", "URL");
                Message = Message.Replace("[username]", doris.Username);
                Message = Message.Replace("[password]", doris.Password);
            } else {
                Message = sMessage;
            }

            try {
                string MyFrom = sender;
                string MyTo = email;
                string MySubject = "[Ticket:" + data.TicketID + "] " + subject;
                string MyBody = Message;

                MAILConnection smtp = FetchSMTP();
              
                /*                string MySmtpMailServerName = "mail.broadpark.no";
                                int MySmtpMailServerPort = 25; //25 is the default for SMTP

                                SmtpClient MySmtpClient = new SmtpClient(MySmtpMailServerName, MySmtpMailServerPort);*/
                
                
                SmtpClient MySmtpClient = new SmtpClient(smtp.Server, smtp.Port);
               
                if (smtp.UseCredentials) {
                    MySmtpClient.Credentials = new NetworkCredential(smtp.Username, smtp.Password);
                }
                if (smtp.UseSSL) {
                    MySmtpClient.EnableSsl = true;
                }
               
                Debug.WriteLine("Sender epost fra " + smtp.Server + ", " + smtp.Port + " identifisert med " + smtp.Username + " og " + smtp.Password);

                //                MySmtpClient.Send(MyFrom, MyTo, MySubject, MyBody);

                /*
                 * Hent inn hvem som vil motta notifikasjon og ikke. FRITZ
                 * */
           /*     if (reply) {
                    mailAboutReply(MySubject, data.TicketID, MySmtpClient, MyFrom, doris, data);
                } else {
                    mailAboutNewMessage(MySubject, data.TicketID, MySmtpClient, MyFrom, doris, data);
                }*/
                /*
                |                   1 | NewQuestions |
                |                   2 | ReplyAll     |
                |                   3 | ReplyMine    |
                 */
                // * MailConfiguration

                using (MailMessage newMail = new MailMessage()) {
                    newMail.From = new MailAddress(MyFrom);
                    //newMail.To.Add(MyTo);
                    newMail.To.Add("doris@doris.doris");
                    newMail.Subject = MySubject;
                    newMail.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(MyBody, null, "text/html"));
                    MySmtpClient.Send(newMail);
                }
             

                Debug.WriteLine("Message sent.");
            } catch (Exception MyError) {
                Debug.WriteLine("An error has occurred: " + MyError.Message);
                //Label8.Text = "'Feil i FetchSMTP' :" + MyError.Message;
                return false;
            }
            Debug.WriteLine("Done sending through smtp");
            return true;
        }

        public DorisUser AddCustomer(String Email, String Fullname, int TicketPriorityID) {

            DorisUser doris = new DorisUser();

            //doris.UserClass UserClass = new doris.UserClass();

            // make the username
/*            String[] unpart = Fullname.Split(new char[] { ' ' });
            for (int i = 0; i < unpart.Count(); i++) {
                if (unpart[i].Length >= 4)
                    unpart[i] = unpart[i].Substring(0, 3);
                else
                    unpart[i] = unpart[i];
            }String.Join("", unpart);*/
            doris.Username = Email;

            // add user
            DorisMembershipProvider provider = new DorisMembershipProvider();
            NameValueCollection config = new NameValueCollection();
            config.Add("name", "DorisMembershipProvider");
            config.Add("type", "DorisMembershipProvider");
            config.Add("applicationName", "/");
            config.Add("connectionStringName", "localConnectionString");

            provider.Initialize("DorisMembershipProvider", config);
            MembershipCreateStatus status = new MembershipCreateStatus();

            doris.CustID = provider.GetUserIDByEmail(Email);

            if (doris.CustID == "") {
                AlphaNumericPasswordGenerator alphaNumeric = new AlphaNumericPasswordGenerator();
                doris.Password = alphaNumeric.Generate(8);
                MembershipUser member = provider.CreateUser(doris.Username, doris.Password, Email, null, null, true, null, out status);
                if (member != null) 
                    doris.CustID = member.ProviderUserKey.ToString();
                else {
                    Debug.WriteLine(status.ToString());
                }
            } else {
                doris.Username = provider.GetUserNameByEmail(Email);
                doris.Password = null;
            }

            Debug.WriteLine("user : " + doris.CustID);

            Label5.Text = doris.CustID;
            Label6.Text = doris.Username;
            Label7.Text = doris.Password;
            
            return doris;
        }

        protected int storeNewMessage(DorisUser doris) {
            int TicketID = 0;
            MySqlConnection conn = new MySqlConnection(WebConfigurationManager.ConnectionStrings["localConnectionString"].ConnectionString);
            try {
            
                conn.Open();
                MySqlCommand cmd = new MySqlCommand();
                cmd.Connection = conn;
                cmd.CommandText = "addTicket";
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add(new MySqlParameter("@in_title", MySqlDbType.VarChar));
                cmd.Parameters["@in_title"].Value = tTitle.Text; ;
                cmd.Parameters["@in_title"].Direction = ParameterDirection.Input;

                cmd.Parameters.Add(new MySqlParameter("@in_userid", MySqlDbType.VarChar));
                cmd.Parameters["@in_userid"].Value = doris.CustID;
                cmd.Parameters["@in_userid"].Direction = ParameterDirection.Input;
              
                cmd.Parameters.Add(new MySqlParameter("@in_ticketpriorityid", MySqlDbType.Int32));
                cmd.Parameters["@in_ticketpriorityid"].Value = 3;
                cmd.Parameters["@in_ticketpriorityid"].Direction = ParameterDirection.Input;
              
                cmd.Parameters.Add(new MySqlParameter("@in_message", MySqlDbType.Text));
                cmd.Parameters["@in_message"].Value = Editor.Text;
                cmd.Parameters["@in_message"].Direction = ParameterDirection.Input;

                cmd.Parameters.Add(new MySqlParameter("@out_ticketid", MySqlDbType.Int32));
                cmd.Parameters["@out_ticketid"].Direction = ParameterDirection.Output;
                
              
                cmd.ExecuteNonQuery();
               
                TicketID = int.Parse(cmd.Parameters["@out_ticketid"].Value.ToString());
              
            
              //  statusid = int.Parse(cmd.Parameters["@out_ticketstatusid"].Value.ToString());
                //                lnkReply.NavigateUrl = "Reply.aspx?id=" + Request.QueryString["id"] + "&d=" + Request.QueryString["d"];
                cmd.Dispose();
            } catch (MySql.Data.MySqlClient.MySqlException ex) {
               // Debug.WriteLine("Error " + ex.Number + " has occurred: " + ex.Message);
              

            } finally {
                conn.Close();
            }
            return TicketID;
        }

        protected void getStatus() {
            MySqlConnection conn = new MySqlConnection(WebConfigurationManager.ConnectionStrings["localConnectionString"].ConnectionString);
            try {
                conn.Open();
                MySqlCommand cmd = new MySqlCommand();
                cmd.Connection = conn;

                cmd.CommandText = "getAllTicketStatus";
                cmd.CommandType = CommandType.StoredProcedure;

                MySqlDataReader reader = cmd.ExecuteReader();

                while (reader.Read()) {
                    lStatus.Items.Add(new ListItem(reader["Status"].ToString(), reader["TicketStatusID"].ToString()));
                }

                cmd.Dispose();                               

            } catch (MySql.Data.MySqlClient.MySqlException ex) {
                Debug.WriteLine("Error " + ex.Number + " has occurred: " + ex.Message);
            } finally {
                conn.Close();
            }


        }

        protected void setDropDownSelectedItem(string selectedItem)
        {
            ListItem selectedListItem = lStatus.Items.FindByValue(selectedItem);
            if (selectedListItem != null)
                selectedListItem.Selected = true;       
        }

        protected void Page_Load(object sender, EventArgs e) {
            if (!Page.IsPostBack) {
                getStatus();
                setDropDownSelectedItem("3");
            }          
        }

        protected void sendButton_Click(object sender, EventArgs e)
        {
            DorisUser doris = AddCustomer(tEmail.Text, tFullname.Text, 1);
            int TicketID = storeNewMessage(doris);
            storeCurrentStatus(TicketID);
            TicketStatus data = GetTicketStatus(TicketID);
            SendTicketResponse(TicketID, doris, data, tTitle.Text, Editor.Text, false);
            Response.Redirect("Ticket.aspx?id=" + TicketID);

        }


    }
}